package file

import (
	"context"
	"fmt"
	"gitee.com/mootok/mootok/src/constant/config"
	"gitee.com/mootok/mootok/src/utils/logging"
	"github.com/qiniu/go-sdk/v7/auth/qbox"
	"github.com/qiniu/go-sdk/v7/storage"
	"github.com/sirupsen/logrus"
	"io"
	"time"
)

type KodoStorage struct {
	mac *qbox.Mac
}

func (f *KodoStorage) GetLink(fileName string, deadline int64, query *string) string {
	if query != nil {
		return storage.MakePrivateURLv2WithQueryString(f.mac, config.EnvConfig.QiNiuKodoDomain, fileName, *query, deadline)
	} else {
		return storage.MakePrivateURLv2(f.mac, config.EnvConfig.QiNiuKodoDomain, fileName, deadline)
	}
}

func (f *KodoStorage) BatchDelete(fileName []string) ([]bool, error) {
	logger := logging.LogService("storage.Qiniu.BatchDelete").WithFields(logrus.Fields{
		"fileName": fileName,
	})
	bucketManager := storage.NewBucketManager(f.mac, &storage.Config{})

	deleteOps := make([]string, 0, len(fileName))
	for _, key := range fileName {
		deleteOps = append(deleteOps, storage.URIDelete(config.EnvConfig.QiNiuKodoBucket, key))
	}
	rets, err := bucketManager.Batch(deleteOps)
	if len(rets) == 0 {
		// 处理错误
		if e, ok := err.(*storage.ErrorInfo); ok {
			logger.Errorf("batch error, code:%d", e.Code)
		} else {
			logger.Errorf("batch error, %s", err)
		}
		return nil, err
	}
	// 返回 rets，先判断 rets 是否
	result := make([]bool, len(rets))
	for i, ret := range rets {
		// 200 为成功
		if ret.Code == 200 {
			result[i] = true
		} else {
			logger.Warningf("failed on %d: %s\n", i, ret.Data.Error)
			result[i] = false
		}
	}
	return result, nil
}

func (f *KodoStorage) UploadToken(fileName string, mimeType string, deadline int64, options *map[string]string) string {
	scope := fmt.Sprintf("%s:%s", config.EnvConfig.QiNiuKodoBucket, fileName)
	putPolicy := storage.PutPolicy{
		Scope:           scope,
		MimeLimit:       mimeType,
		IsPrefixalScope: 0,
		Expires:         uint64(deadline - time.Now().Unix()),
	}
	if options != nil {
		putPolicy.PersistentOps = (*options)["persistentOps"]
	}
	return putPolicy.UploadToken(f.mac)
}

func (f *KodoStorage) UploadFile(destFileName string, input io.Reader, UploadToken string) error {
	cfg := storage.Config{}
	formUploader := storage.NewFormUploader(&cfg)
	ret := storage.PutRet{}
	putExtra := storage.PutExtra{}
	err := formUploader.Put(context.Background(), &ret, UploadToken, destFileName, input, -1, &putExtra)
	return err

}

func (f *KodoStorage) IsExists(fileName string) (bool, error) {
	bucketManager := storage.NewBucketManager(f.mac, &storage.Config{})
	items, _, _ ,_ , err := bucketManager.ListFiles(config.EnvConfig.QiNiuKodoBucket, fileName, "", "", 1)
	if err != nil {
		return false, err
	}
	if len(items) > 0 {
		return true, nil
	}
	return false, nil

}